package com.hamilton.erik.pt.mobile.android;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

import com.android.volley.Response;
import com.hamilton.erik.pt.core.model.Animal;
import com.hamilton.erik.pt.core.model.Note;
import com.hamilton.erik.pt.mobile.android.volley.response.error.listener.DisplayErrorErrorListener;
import com.hamilton.erik.pt.mobile.android.widget.NoteListAdapter;
import com.hamilton.erik.pt.mobile.client.VolleyJsonRestClient;
import com.hamilton.erik.pt.mobile.util.JsonUtil;
import com.hamilton.erik.pt.mobile.util.ResultUtil;

public class NoteListActivity extends ListActivity {

	private Animal animal = null;
	private String baseRestPath = null;
	private long referenceId = -1;
	private String titleNoteType = "";
	private List<Note> notes = null;
	private ProgressDialog progressDialog = null;
	
	private final int VIEW_NOTE_ACTIVITY = 0;
	private final int ADD_NOTE_ACTIVITY = 1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_note_list);

		animal = (Animal)getIntent()
							.getSerializableExtra(
								getString(R.string.extra_animal_object));
		
		titleNoteType = getIntent()
							.getStringExtra(
								getString(R.string.extra_note_title_type));
		if(titleNoteType == null) titleNoteType = "";
		
		if(!TextUtils.isEmpty(animal.getName())) {
			setTitle(animal.getName() + "'s " + titleNoteType + " Notes");
		}
		
		baseRestPath = getIntent()
						.getStringExtra(
								getString(R.string.extra_note_base_rest_path));
		
		referenceId = getIntent()
							.getLongExtra(
								getString(R.string.extra_note_reference_id), -1);

		findViewById(R.id.note_list_view_add_note_button).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						add();
					}
				});
		
		createList();
	}
	
	protected void createList() {
		// Note the retrieveNotess will populate the list on success.
		// This is done because if the retrieve isn't completed by the
		// time the populate is called, we will have a null pointer.
		// We must wait for the retrieval to be successful before continuing.
		if(notes == null) {
			retrieveList();	
		}
		else {
			populateList();
		}
		
		ListView listView = (ListView)findViewById(R.id.note_list_view);
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			  @Override
			  public void onItemClick(AdapterView<?> parent, final View view,
			    int position, long id) {
				  view(parent.getItemAtPosition(position));
			  }
			});
	}
	
	protected void retrieveList() {
		StringBuilder url = new StringBuilder(baseRestPath);
		url.append("/retrieve/notes/").append(referenceId);
		
		if (progressDialog == null) {
	        progressDialog = new ProgressDialog(this);
	        progressDialog.setTitle(getString(R.string.progress_loading_title));
	        progressDialog.setMessage(getString(R.string.note_list_progress_retrieving_notes));
	    }
	    progressDialog.show();
		
		VolleyJsonRestClient.getClient().getJsonArray(url.toString(),
								new RetrieveNoteListSuccessListener(),
								new DisplayErrorErrorListener(this, progressDialog));
	}
	
	protected void populateList() {
		NoteListAdapter adapter = new NoteListAdapter(this, notes);
		
		ListView listView = (ListView)findViewById(R.id.note_list_view);
		listView.setAdapter(adapter);
		adapter.notifyDataSetChanged();
	}
	
	protected void add() {
		Note note = new Note();
		note.setReferenceId(referenceId);
		
		Intent editNoteActivity = new Intent(getApplicationContext(), EditNoteActivity.class);
		editNoteActivity.putExtra(getString(R.string.extra_animal_object), animal);
		editNoteActivity.putExtra(getString(R.string.extra_note_object), note);
		editNoteActivity.putExtra(getString(R.string.extra_note_title_type), titleNoteType);
		editNoteActivity.putExtra(getString(R.string.extra_note_base_rest_path), baseRestPath);
		startActivity(editNoteActivity);
	}
	
	protected void view(Object object) {
		Note selectedNote = (Note)object;
		
		Intent viewNoteActivity = new Intent(getApplicationContext(), ViewNoteActivity.class);
		viewNoteActivity.putExtra(getString(R.string.extra_animal_object), animal);
		viewNoteActivity.putExtra(getString(R.string.extra_note_object), selectedNote);
		viewNoteActivity.putExtra(getString(R.string.extra_note_title_type), titleNoteType);
		viewNoteActivity.putExtra(getString(R.string.extra_note_base_rest_path), baseRestPath);
		startActivityForResult(viewNoteActivity, VIEW_NOTE_ACTIVITY);
	}

	private class RetrieveNoteListSuccessListener
							implements Response.Listener<JSONArray> {

		@Override
		public void onResponse(JSONArray response) {
			notes = new ArrayList<Note>();
			if(response != null) {
				try {
					for(int i = 0; i < response.length(); i++) {
						notes.add(
								JsonUtil.getInstance()
									.getNote(response.getJSONObject(i)));
					}
					
					populateList();
					
					if(progressDialog != null && progressDialog.isShowing()) {
						progressDialog.dismiss();
					}
				} catch (Exception e) {
					Log.e("NoteListActivity",
							String.format("%s: %s","Failed to convert JSONObject to Note.", e.getMessage()));
				}
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.note_list, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		switch(item.getItemId()) {
			default :
				return super.onOptionsItemSelected(item);
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		if(requestCode == VIEW_NOTE_ACTIVITY &&
			(resultCode == ResultUtil.EDITED ||
			 resultCode == ResultUtil.DELETED)) {
			retrieveList();
			populateList();
		}
		else if(requestCode == ADD_NOTE_ACTIVITY &&
				resultCode == ResultUtil.RESULT_SUCCESS) {
			retrieveList();
			populateList();
		}
	}

}
